﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using GMap.NET;

namespace MyPoints.UserControls
{
  /// <summary>
  /// Interaction logic for WptList.xaml
  /// </summary>
  public partial class WptList : UserControl
  {
    private Dictionary<string, Expander> cats = new Dictionary<string, Expander>();
    private Dictionary<wptType, Label> lbls = new Dictionary<wptType, Label>();

    public delegate void WptClickHandler(WptList sender, wptType wpt);
    public event WptClickHandler WptClick;

    public WptList()
    {
      InitializeComponent();
    }

    public void Init()
    {
      EraseAllWpt();
    }

    internal void EraseAllWpt()
    {
      cats.Clear();
      pnl.Children.Clear();
      lbls.Clear();

      GetCategoryExpander(null);
    }

    internal void AddWpts(IEnumerable<wptType> wpts)
    {
      foreach (var wpt in wpts)
      {
        AddWpt(wpt, false);
      }
    }

    public void AddWpt(wptType wpt, bool expand = true)
    {
      
      Label lbl = CreateLabel(wpt);
      _AddLbl(lbl, expand);      
    }

    internal void UpdateWptsTitle(wptType wpt)
    {
      Label lbl;
      lbl = lbls[wpt];

      TextBlock tb = (TextBlock)lbl.Content;
      tb.Text = wpt.name;
    }

    internal void UpdateWptsCategory(wptType wpt)
    {
      Label lbl;
      lbl = lbls[wpt];

      _RemoveLbl(lbl);
      _AddLbl(lbl, true);
    }

    private Label CreateLabel(wptType wpt)
    {
      TextBlock tb = new TextBlock();
      tb.Text = wpt.name;
      tb.TextWrapping = TextWrapping.Wrap;

      Label ret = new Label();
      ret.Tag = wpt;
      ret.Content = tb;
      ret.MouseEnter += wptLabelMouseEnter;
      ret.MouseLeave += wptLabelMouseLeave;
      ret.MouseUp += wptLabelMouseUp;

      lbls.Add(wpt, ret);

      return ret;
    }

    private void wptLabelMouseLeave(object sender, MouseEventArgs e)
    {
      Label lbl = sender as Label;
      lbl.Background = new SolidColorBrush(Colors.Transparent);
      StackPanel sp = lbl.Parent as StackPanel;
      Expander exp = sp.Parent as Expander;
      lbl.Foreground = exp.Foreground;
      TextBlock tb = lbl.Content as TextBlock;
      tb.TextDecorations = null;
    }

    private void wptLabelMouseEnter(object sender, MouseEventArgs e)
    {
      Label lbl = sender as Label;
      lbl.Background = new SolidColorBrush(Colors.Linen);
      TextBlock tb = lbl.Content as TextBlock;

      TextDecorationCollection tdc = new TextDecorationCollection();
      TextDecoration underline = new TextDecoration(); // underline is the default
      tdc.Add(underline);
      tb.TextDecorations = tdc;
    }

    private void wptLabelMouseUp(object sender, MouseButtonEventArgs e)
    {
      Label lbl = sender as Label;
      wptType wpt = lbl.Tag as wptType;

      if (WptClick != null)
        WptClick(this, wpt);
    }

    private Expander GetCategoryExpander(string key)
    {
      if (string.IsNullOrEmpty(key))
      {
        key = Shared.sett.user.list.emptyTypeString;
      }

      if (cats.ContainsKey(key) == false)
      {
        Expander ex = new Expander();

        // header
        StackPanel sp;
        
        sp = new StackPanel();
        sp.Orientation = Orientation.Horizontal;
        Label lb = new Label() { Width = 16};
        lb.Background = new SolidColorBrush(Shared.GetMarkerFillColorForWptType(key));
        sp.Children.Add(lb);

        TextBlock tb = new TextBlock() { Text = key };
        sp.Children.Add(tb);
        ex.Header = sp;


        // content
        sp = new StackPanel();
        ex.Content = sp;
        pnl.Children.Add(ex);

        cats.Add(key, ex);
      }

      return cats[key];
    }

    public void RemoveWpt(wptType wpt)
    {
      Label lbl = lbls[wpt];
      _RemoveLbl(lbl);
    }

    private void _RemoveLbl(Label lbl)
    {
      StackPanel stc;
      Expander ex;

      stc = (StackPanel)lbl.Parent;
      stc.Children.Remove(lbl);

      if (stc.Children.Count == 0)
      {
        ex = (Expander)stc.Parent;

        string key = ((ex.Header as StackPanel).Children[1] as TextBlock).Text;
        cats.Remove(key);
        this.pnl.Children.Remove(ex);
        ex = null;
      }
    }
    private void _AddLbl(Label lbl, bool expand)
    {
      wptType wpt = lbl.Tag as wptType;
      Expander cex = GetCategoryExpander(wpt.type);
      StackPanel csp = cex.Content as StackPanel;
      csp.Children.Add(lbl);

      if (expand)
        cex.IsExpanded = true;
    }

    internal void Expand(string categoryName)
    {
      if (categoryName == null)
        categoryName = Shared.sett.user.list.emptyTypeString;
      Expander ex = cats[categoryName];
      ex.IsExpanded = true;
    }

    internal void CollapseAll()
    {
      foreach (Expander ex in pnl.Children)
      {
        ex.IsExpanded = false;
      }
    }    
  }
}
